using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Windows.Forms;

namespace FileCopyTool
{
    public partial class MainForm : Form
    {
        private BackgroundWorker copyWorker;
        private List<string> filesToCopy;
        private bool isCancelled;
        private int totalFiles;
        private int copiedFiles;
        private int skippedFiles;
        private int failedFiles;

        public MainForm()
        {
            InitializeComponent();
            InitializeBackgroundWorker();
            InitializeFileExtensions();
        }

        private void InitializeFileExtensions()
        {
            // 添加默认文件后缀
            lstExtensions.Items.Add(".pptx");
            lstExtensions.Items.Add(".png");
        }

        private void InitializeBackgroundWorker()
        {
            copyWorker = new BackgroundWorker();
            copyWorker.WorkerReportsProgress = true;
            copyWorker.WorkerSupportsCancellation = true;
            copyWorker.DoWork += CopyWorker_DoWork;
            copyWorker.ProgressChanged += CopyWorker_ProgressChanged;
            copyWorker.RunWorkerCompleted += CopyWorker_RunWorkerCompleted;
        }

        private void btnSourceBrowse_Click(object sender, EventArgs e)
        {
            using (FolderBrowserDialog dialog = new FolderBrowserDialog())
            {
                dialog.Description = "选择源文件夹";
                dialog.ShowNewFolderButton = false;
                
                // 支持网络路径
                if (!string.IsNullOrEmpty(txtSourcePath.Text) && Directory.Exists(txtSourcePath.Text))
                {
                    dialog.SelectedPath = txtSourcePath.Text;
                }

                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    txtSourcePath.Text = dialog.SelectedPath;
                }
            }
        }

        private void btnDestBrowse_Click(object sender, EventArgs e)
        {
            using (FolderBrowserDialog dialog = new FolderBrowserDialog())
            {
                dialog.Description = "选择目标文件夹";
                dialog.ShowNewFolderButton = true;
                
                // 支持网络路径
                if (!string.IsNullOrEmpty(txtDestPath.Text) && Directory.Exists(txtDestPath.Text))
                {
                    dialog.SelectedPath = txtDestPath.Text;
                }

                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    txtDestPath.Text = dialog.SelectedPath;
                }
            }
        }

        private void btnAddExtension_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrWhiteSpace(txtNewExtension.Text))
            {
                string extension = txtNewExtension.Text.Trim();
                // 确保扩展名以点开头
                if (!extension.StartsWith("."))
                {
                    extension = "." + extension;
                }

                // 检查是否已存在
                if (!lstExtensions.Items.Contains(extension))
                {
                    lstExtensions.Items.Add(extension);
                    txtNewExtension.Clear();
                    LogMessage($"已添加文件类型: {extension}");
                }
                else
                {
                    MessageBox.Show("该文件类型已存在", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
        }

        private void btnRemoveExtension_Click(object sender, EventArgs e)
        {
            if (lstExtensions.SelectedItem != null)
            {
                string extension = lstExtensions.SelectedItem.ToString();
                lstExtensions.Items.Remove(lstExtensions.SelectedItem);
                LogMessage($"已移除文件类型: {extension}");
            }
            else
            {
                MessageBox.Show("请先选择要移除的文件类型", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void btnStartCopy_Click(object sender, EventArgs e)
        {
            if (!ValidateInput())
            {
                return;
            }

            PrepareCopyOperation();
            copyWorker.RunWorkerAsync();
        }

        private bool ValidateInput()
        {
            bool isValid = true;
            errorProvider.Clear();

            if (string.IsNullOrWhiteSpace(txtSourcePath.Text) || !Directory.Exists(txtSourcePath.Text))
            {
                errorProvider.SetError(txtSourcePath, "请选择有效的源文件夹");
                isValid = false;
            }

            if (string.IsNullOrWhiteSpace(txtDestPath.Text))
            {
                errorProvider.SetError(txtDestPath, "请选择目标文件夹");
                isValid = false;
            }
            else
            {
                // 尝试创建目标文件夹（如果不存在）
                try
                {
                    if (!Directory.Exists(txtDestPath.Text))
                    {
                        Directory.CreateDirectory(txtDestPath.Text);
                    }
                }
                catch (Exception ex)
                {
                    errorProvider.SetError(txtDestPath, $"无法创建目标文件夹: {ex.Message}");
                    isValid = false;
                }
            }

            if (lstExtensions.Items.Count == 0)
            {
                MessageBox.Show("请至少添加一种文件类型", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                isValid = false;
            }

            return isValid;
        }

        private void PrepareCopyOperation()
        {
            // 初始化复制统计
            totalFiles = 0;
            copiedFiles = 0;
            skippedFiles = 0;
            failedFiles = 0;
            isCancelled = false;
            txtLog.Clear();
            
            // 查找所有符合条件的文件
            filesToCopy = new List<string>();
            string sourcePath = txtSourcePath.Text;
            
            foreach (string extension in lstExtensions.Items)
            {
                try
                {
                    string[] files = Directory.GetFiles(sourcePath, $"*{extension}", SearchOption.AllDirectories);
                    filesToCopy.AddRange(files);
                }
                catch (Exception ex)
                {
                    LogMessage($"搜索文件时出错: {ex.Message}");
                }
            }
            
            totalFiles = filesToCopy.Count;
            progressBar.Maximum = totalFiles;
            progressBar.Value = 0;
            
            // 更新UI状态
            UpdateUIState(false);
            LogMessage($"找到 {totalFiles} 个符合条件的文件，准备开始复制...");
            lblStatus.Text = $"状态：准备复制 ({copiedFiles}/{totalFiles})";
        }

        private void UpdateUIState(bool isIdle)
        {
            btnStartCopy.Enabled = isIdle;
            btnCancel.Enabled = !isIdle;
            btnSourceBrowse.Enabled = isIdle;
            btnDestBrowse.Enabled = isIdle;
            btnAddExtension.Enabled = isIdle;
            btnRemoveExtension.Enabled = isIdle;
            txtSourcePath.Enabled = isIdle;
            txtDestPath.Enabled = isIdle;
            txtNewExtension.Enabled = isIdle;
            lstExtensions.Enabled = isIdle;
            rdbOnlyFiles.Enabled = isIdle;
            rdbCopyWithParentFolder.Enabled = isIdle;
            rdbPreserveStructure.Enabled = isIdle;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            if (copyWorker.IsBusy)
            {
                isCancelled = true;
                btnCancel.Text = "取消中...";
                btnCancel.Enabled = false;
                copyWorker.CancelAsync();
            }
        }

        private void CopyWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            
            for (int i = 0; i < filesToCopy.Count; i++)
            {
                if (worker.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }

                string sourceFile = filesToCopy[i];
                string destFile = GetDestinationFilePath(sourceFile);
                
                try
                {
                    // 检查目标文件是否存在
                    if (File.Exists(destFile))
                    {
                        // 比较文件大小
                        FileInfo sourceInfo = new FileInfo(sourceFile);
                        FileInfo destInfo = new FileInfo(destFile);
                        
                        if (sourceInfo.Length == destInfo.Length)
                        {
                            // 文件大小相同，跳过
                            skippedFiles++;
                            worker.ReportProgress(i + 1, new CopyStatus { FileName = sourceFile, Status = CopyStatusType.Skipped });
                            continue;
                        }
                    }
                    
                    // 确保目标目录存在
                    string destDirectory = Path.GetDirectoryName(destFile);
                    if (!Directory.Exists(destDirectory))
                    {
                        Directory.CreateDirectory(destDirectory);
                    }
                    
                    // 复制文件
                    File.Copy(sourceFile, destFile, true);
                    copiedFiles++;
                    worker.ReportProgress(i + 1, new CopyStatus { FileName = sourceFile, Status = CopyStatusType.Copied });
                }
                catch (Exception ex)
                {
                    failedFiles++;
                    worker.ReportProgress(i + 1, new CopyStatus { FileName = sourceFile, Status = CopyStatusType.Failed, ErrorMessage = ex.Message });
                }
            }
        }

        // 根据选择的复制模式获取目标文件路径
        private string GetDestinationFilePath(string sourceFile)
        {
            string sourceRoot = txtSourcePath.Text;
            string destRoot = txtDestPath.Text;
            
            // 确保路径以统一的分隔符结尾
            if (!sourceRoot.EndsWith(Path.DirectorySeparatorChar.ToString()))
                sourceRoot += Path.DirectorySeparatorChar;
                
            // 保持完整结构（默认）
            if (rdbPreserveStructure.Checked)
            {
                return Path.Combine(destRoot, sourceFile.Substring(sourceRoot.Length));
            }
            // 只复制文件，不包含文件夹结构
            else if (rdbOnlyFiles.Checked)
            {
                string fileName = Path.GetFileName(sourceFile);
                return Path.Combine(destRoot, fileName);
            }
            // 复制文件及直接父文件夹
            else // rdbCopyWithParentFolder.Checked
            {
                string parentFolder = Path.GetFileName(Path.GetDirectoryName(sourceFile));
                string fileName = Path.GetFileName(sourceFile);
                return Path.Combine(destRoot, parentFolder, fileName);
            }
        }

        private void CopyWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar.Value = e.ProgressPercentage;
            
            if (e.UserState is CopyStatus status)
            {
                string message = $"{DateTime.Now:HH:mm:ss} - ";
                switch (status.Status)
                {
                    case CopyStatusType.Copied:
                        message += $"已复制: {status.FileName}";
                        break;
                    case CopyStatusType.Skipped:
                        message += $"已跳过: {status.FileName} (文件已存在且大小相同)";
                        break;
                    case CopyStatusType.Failed:
                        message += $"复制失败: {status.FileName} ({status.ErrorMessage})";
                        break;
                }
                
                LogMessage(message);
                lblStatus.Text = $"状态：正在复制 ({copiedFiles}/{totalFiles})";
            }
        }

        private void CopyWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                LogMessage("复制操作已被取消");
                lblStatus.Text = $"状态：已取消 (已复制 {copiedFiles}/{totalFiles})";
            }
            else if (e.Error != null)
            {
                LogMessage($"复制过程中发生错误: {e.Error.Message}");
                lblStatus.Text = "状态：出错";
            }
            else
            {
                LogMessage($"复制完成 - 总计: {totalFiles}, 已复制: {copiedFiles}, 已跳过: {skippedFiles}, 失败: {failedFiles}");
                lblStatus.Text = $"状态：完成 ({copiedFiles}/{totalFiles})";
            }
            
            // 恢复UI状态
            UpdateUIState(true);
            btnCancel.Text = "取消";
        }

        private void LogMessage(string message)
        {
            if (txtLog.InvokeRequired)
            {
                txtLog.Invoke(new Action<string>(LogMessage), message);
            }
            else
            {
                txtLog.AppendText(message + Environment.NewLine);
                txtLog.ScrollToCaret();
            }
        }

        private void txtSourcePath_TextChanged(object sender, EventArgs e)
        {
            errorProvider.SetError(txtSourcePath, string.Empty);
        }

        private void txtDestPath_TextChanged(object sender, EventArgs e)
        {
            errorProvider.SetError(txtDestPath, string.Empty);
        }

        // 复制状态枚举
        private enum CopyStatusType
        {
            Copied,
            Skipped,
            Failed
        }

        // 复制状态信息类
        private class CopyStatus
        {
            public string FileName { get; set; }
            public CopyStatusType Status { get; set; }
            public string ErrorMessage { get; set; }
        }
    }
}
    